/*
 * algo.c
 *
 *  Created on: 29/12/2011
 *      Author: utn_so
 */

#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <sys/mman.h>
#include <unistd.h>

#include "libPaquetes.h"
#include "tiposPaquetes.h"

#define IP "192.168.1.102"
#define PUERTO "2348"
#define MAX_BUFFER 5000

void main(void) {
	FILE* fp = fopen("/home/utn_so/Escritorio/fat32.disk", "w+");
	while (fp == NULL) {
		printf("Error al leer el disco.\n");
		printf("Presione enter.\n");
		fflush(stdin);
		getchar();
		fp = fopen("/home/utn_so/Escritorio/fat32.disk", "w+");
	}
	struct sockaddr_in *local_address;
	struct sockaddr_in *remote_address;
	int32_t descriptor;
	descriptor = (int32_t) socket(AF_INET, SOCK_STREAM, 0);
	local_address = malloc(sizeof(struct sockaddr_in));
	remote_address = malloc(sizeof(struct sockaddr_in));

	{
		local_address->sin_family = AF_INET;
		local_address->sin_addr.s_addr = INADDR_ANY;
		local_address->sin_port = htons((atoi(PUERTO)));
		memset(local_address->sin_zero, 0, 8);
	}
	{
		local_address->sin_family = AF_INET;
		memset(remote_address->sin_zero, 0, 8);
	}
	bind(descriptor, (struct sockaddr *) local_address, sizeof(struct sockaddr_in));

	listen(descriptor, sizeof(int32_t));
	printf("Estoy a la escucha\n");
	uint32_t addrlen = sizeof(struct sockaddr_in);
	int32_t remote_client;
	memset(remote_address->sin_zero, 0, 8);
	remote_client = accept(descriptor, (struct sockaddr*) remote_address, (void*) &addrlen);
	while (1) {
		if (remote_client <= 0) {
			perror("accept()");
		} else {
			char* buffer = (char*) malloc(MAX_BUFFER);
			memset(buffer, '\0', MAX_BUFFER);
			int32_t resRecv = recv(remote_client, buffer, MAX_BUFFER, 0);
			if (resRecv < 0) {
				perror("recv()");
			} else {
				printf("Recibi: [%d].\n", resRecv);
				//RESPONDO

				if (buffer[0] == 0) {
					//HANDSHAKE
					printf("Me llego un pedido de handshake.\n");
					int32_t resSend = send(remote_client, "\0\0\0", 5, 0);
					if (resSend < 0) {
						perror("send()");
					} else {
						printf("Envie un handshake.\n");
					}
				} else if (buffer[0] == 1) {
					//LEER
					printf("Me llego un pedido de lectura.\n");
					t_paquete paqueteRecibido;
					printf("aca rompe 1.\n");
					empaquetar(buffer, &paqueteRecibido);
					printf("aca rompe 2.\n");
					t_paquete_lectura paqueteLectura;
					paqueteAPaqueteLectura(paqueteRecibido, &paqueteLectura);
					printf("aca rompe 3.\n");
					t_paquete_escritura paqueteEscritura;
					paqueteEscritura.payLoad = NULL;
					printf("aca rompe 4.\n");
					free(paqueteEscritura.payLoad);
					paqueteEscritura.payLoad = malloc(sizeof(payLoad_Escritura) * 8);
					printf("aca rompe 5.\n");
					uint8_t i;
					for (i = 0; i < (paqueteLectura.pLength / 8); i++) {
						fseek(fp, (paqueteLectura.payLoad[i] * 512), SEEK_SET);
						char* sector = (char*) malloc(512);
						fread(sector, 512, 1, fp);
						paqueteEscritura.payLoad[i].numSector = paqueteLectura.payLoad[i];
						memcpy(paqueteEscritura.payLoad[i].contenidoSector, sector, 512);
					}
					t_paquete paqueteAEnviar;
					paqueteEscrituraAPaquete(paqueteEscritura, &paqueteAEnviar);
					char* envio;
					desempaquetar(paqueteAEnviar, &envio);
					int32_t resSend = send(remote_client, envio, strlen(envio), 0);
					if (resSend < 0) {
						perror("send()");
					} else {
						printf("Envie un paquete de escritura.\n");
					}
				}
			}
			free(buffer);
		}
	}
}
